using Lzfy_Refund_Service.Models;
using Lzfy_Refund_Service.Repositories;

namespace Lzfy_Refund_Service.Services
{
    public class PermissionService : IPermissionService
    {
        private readonly IPermissionRepository _permissionRepository;
        private readonly IRoleRepository _roleRepository;
        private readonly IUserRepository _userRepository;

        public PermissionService(
            IPermissionRepository permissionRepository,
            IRoleRepository roleRepository,
            IUserRepository userRepository)
        {
            _permissionRepository = permissionRepository;
            _roleRepository = roleRepository;
            _userRepository = userRepository;
        }

        public async Task<List<MenuDto>> GetMenuTreeAsync(MenuTreeRequest request)
        {
            return await _permissionRepository.GetMenuTreeAsync(request);
        }

        public async Task<List<MenuDto>> GetAllMenusAsync()
        {
            return await _permissionRepository.GetAllMenusAsync();
        }

        public async Task<MenuDto?> GetMenuByIdAsync(int id)
        {
            var menu = await _permissionRepository.GetMenuByIdAsync(id);
            if (menu == null) return null;

            return new MenuDto
            {
                Id = menu.Id,
                ParentId = menu.ParentId,
                MenuName = menu.MenuName,
                MenuCode = menu.MenuCode,
                MenuType = menu.MenuType,
                Path = menu.Path,
                Icon = menu.Icon,
                SortOrder = menu.SortOrder,
                IsActive = menu.IsActive,
                Description = menu.Description
            };
        }

        public async Task<int> CreateMenuAsync(MenuDto menuDto)
        {
            // 验证菜单代码是否已存在
            if (await _permissionRepository.MenuCodeExistsAsync(menuDto.MenuCode))
            {
                throw new InvalidOperationException("菜单代码已存在");
            }

            // 如果有父菜单，验证父菜单是否存在
            if (menuDto.ParentId.HasValue && menuDto.ParentId > 0)
            {
                var parentMenu = await _permissionRepository.GetMenuByIdAsync(menuDto.ParentId.Value);
                if (parentMenu == null)
                {
                    throw new InvalidOperationException("父菜单不存在");
                }
            }

            var menu = new Menu
            {
                ParentId = menuDto.ParentId,
                MenuName = menuDto.MenuName,
                MenuCode = menuDto.MenuCode,
                MenuType = menuDto.MenuType,
                Path = menuDto.Path,
                Icon = menuDto.Icon,
                SortOrder = menuDto.SortOrder,
                IsActive = menuDto.IsActive,
                Description = menuDto.Description
            };

            return await _permissionRepository.AddMenuAsync(menu);
        }

        public async Task<bool> UpdateMenuAsync(int id, MenuDto menuDto)
        {
            // 验证菜单是否存在
            var existingMenu = await _permissionRepository.GetMenuByIdAsync(id);
            if (existingMenu == null)
            {
                throw new InvalidOperationException("菜单不存在");
            }

            // 验证菜单代码是否已被其他菜单使用
            if (await _permissionRepository.MenuCodeExistsAsync(menuDto.MenuCode, id))
            {
                throw new InvalidOperationException("菜单代码已存在");
            }

            // 如果有父菜单，验证父菜单是否存在且不是自己
            if (menuDto.ParentId.HasValue && menuDto.ParentId > 0)
            {
                if (menuDto.ParentId == id)
                {
                    throw new InvalidOperationException("不能将自己设为父菜单");
                }

                var parentMenu = await _permissionRepository.GetMenuByIdAsync(menuDto.ParentId.Value);
                if (parentMenu == null)
                {
                    throw new InvalidOperationException("父菜单不存在");
                }
            }

            var menu = new Menu
            {
                Id = id,
                ParentId = menuDto.ParentId,
                MenuName = menuDto.MenuName,
                MenuCode = menuDto.MenuCode,
                MenuType = menuDto.MenuType,
                Path = menuDto.Path,
                Icon = menuDto.Icon,
                SortOrder = menuDto.SortOrder,
                IsActive = menuDto.IsActive,
                Description = menuDto.Description
            };

            return await _permissionRepository.UpdateMenuAsync(menu);
        }

        public async Task<bool> DeleteMenuAsync(int id)
        {
            // 验证菜单是否存在
            var existingMenu = await _permissionRepository.GetMenuByIdAsync(id);
            if (existingMenu == null)
            {
                throw new InvalidOperationException("菜单不存在");
            }

            return await _permissionRepository.DeleteMenuAsync(id);
        }

        public async Task<bool> ToggleMenuStatusAsync(int id, bool isActive)
        {
            // 验证菜单是否存在
            var existingMenu = await _permissionRepository.GetMenuByIdAsync(id);
            if (existingMenu == null)
            {
                throw new InvalidOperationException("菜单不存在");
            }

            return await _permissionRepository.ToggleMenuStatusAsync(id, isActive);
        }

        public async Task<bool> AssignPermissionsAsync(AssignPermissionRequest request)
        {
            if (request.Type == "role")
            {
                // 验证角色是否存在
                var role = await _roleRepository.GetRoleByIdAsync(request.TargetId);
                if (role == null)
                {
                    throw new InvalidOperationException("角色不存在");
                }

                return await _permissionRepository.AssignRolePermissionsAsync(request.TargetId, request.MenuIds);
            }
            else if (request.Type == "user")
            {
                // 验证用户是否存在
                var user = await _userRepository.GetUserByIdAsync(request.TargetId);
                if (user == null)
                {
                    throw new InvalidOperationException("用户不存在");
                }

                // 用户权限通过角色管理，这里可以扩展直接分配用户权限的功能
                throw new NotImplementedException("暂不支持直接为用户分配权限，请通过角色管理");
            }
            else
            {
                throw new InvalidOperationException("无效的分配类型");
            }
        }

        public async Task<List<MenuDto>> GetRolePermissionsAsync(int roleId)
        {
            // 验证角色是否存在
            var role = await _roleRepository.GetRoleByIdAsync(roleId);
            if (role == null)
            {
                throw new InvalidOperationException("角色不存在");
            }

            return await _permissionRepository.GetRoleMenusAsync(roleId);
        }

        public async Task<List<MenuDto>> GetUserPermissionsAsync(int userId)
        {
            // 验证用户是否存在
            var user = await _userRepository.GetUserByIdAsync(userId);
            if (user == null)
            {
                throw new InvalidOperationException("用户不存在");
            }

            return await _permissionRepository.GetUserMenusAsync(userId);
        }
    }
}